package com.colabo.j2ee.web.oaf.security.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.colabo.j2ee.web.core.exception.ServiceException;
import com.colabo.j2ee.web.core.persistence.HqlWrapper;
import com.colabo.j2ee.web.core.pkgenerator.IPKGenerator;
import com.colabo.j2ee.web.core.service.impl.DefaultServiceImpl;
import com.colabo.j2ee.web.core.util.PropertyUtil;
import com.colabo.j2ee.web.core.util.StringUtil;
import com.colabo.j2ee.web.core.vo.SessionUserHolder;
import com.colabo.j2ee.web.oaf.common.AppConstants;
import com.colabo.j2ee.web.oaf.monitorperspective.ILogDataService;
import com.colabo.j2ee.web.oaf.security.ISecurityStrategyService;
import com.colabo.j2ee.web.oaf.security.model.IPArcSecurityStrategyVO;
import com.colabo.j2ee.web.oaf.vo.IPAuditLogVO;

public class SecurityStrategyServiceImpl extends DefaultServiceImpl implements ISecurityStrategyService {
	// 密码输入错误几次被锁定
	private static final String MAX_FAILED_LOGIN_COUNT = "max_failed_login_count";
	// 默认密码
	private static final String DEFAILT_PASSWORD = "default_password";
	// 超级拥护角色,暂时不用
	private static final String ADMIN_ROLECODE = "admin.rolecode";
	// 超级用户名
	private static final String ADMIN_STAFFID = "admin.staffid";
	// 密码过期天数,默认180天
	private static final String PASSWORD_EXPIRE_DAYS = "password_expire_days";
	// 密码与几次历史密码不能重复
	private static final String PASSWORD_MODIFIED_TIMES = "password_modified_times";
	// 密码强制最低长度,最长为20
	private static final String PASSWORD_MIN_LENGTH = "password_min_length";
	// 首次登录是否需要更改密码
	private static final String FIRST_MODIFY_PASSWORD = "first_modify_password";
	// 密码是否使用组合方式,即最高安全方式
	private static final String PASSWORD_NEED_ZUHE = "password_need_zuhe";
	// 系统session数目
	private static final String SYSTEM_SESSION = "system_session";
	// 用户session数目
	private static final String USER_SESSION = "user_session";

	// 默认超级用户名
	private static final String DEFAULT_ADMIN_STAFFID = "admin";
	// 默认角色,暂时不用
	private static final String DEFAULT_ADMIN_ROLECODE = "";
	// 默认密码
	private static final String DEFAULT_DEFAULT_PASSWORD = "123456";
	// 密码输入错误几次被锁定默认
	private static final int DEFAULT_MAX_FAILED_LOGIN_COUNT = 3;
	// 密码默认过期天数
	private static final int DEFAULT_PASSWORD_EXPIRE_DAYS = 180;
	// 默认与历史密码几次比较
	private static final int DEFAULT_PASSWORD_MODIFIED_TIMES = 3;
	// 默认密码最短长度
	private static final int DEFAULT_PASSWORD_MIN_LENGTH = 6;
	// 系统默认sesion数目
	private static final int DEFAULT_SYSTEM_SESSION = 1000;
	// 用户默认sesion数目
	private static final int DEFAULT_USER_SESSION = 3;
	// 密码设置方式
	private static final String PWD_SETTING = "pwd_setting";
	// 默认密码设置方式
	private static final String DEFAULT_PWD_SETTING = "1,1,0,0";
	// 密码设置方式
	private static final String AUTO_ENABLE_TIME = "auto_enable_time";
	// 默认密码设置方式
	private static final String DEFAULT_AUTO_ENABLE_TIME = "-1";

	private ILogDataService logDataService = null;

	private Map strategyMap;

	private final Log logger = LogFactory.getLog(this.getClass());

	// 目前数据库中读取安全策略
	private boolean loadStrategyFromDb = true;

	public boolean isLoadStrategyFromDb() {
		return loadStrategyFromDb;
	}

	public void setLoadStrategyFromDb(boolean loadStrategyFromDb) {
		this.loadStrategyFromDb = loadStrategyFromDb;
	}

	public void init() throws ServiceException {
		strategyMap = new HashMap();
		// 初始化数据库中的安全策略
		if (loadStrategyFromDb) {
			List straDb = findAll_Hibernate_Object(IPArcSecurityStrategyVO.class);
			for (Iterator it = straDb.iterator(); it.hasNext();) {
				IPArcSecurityStrategyVO stra = (IPArcSecurityStrategyVO) it.next();
				strategyMap.put(stra.getStrategyName().toLowerCase(), stra);
			}
		}
	}

	public List getAllStrategies() throws ServiceException {
		return (findAll_Hibernate_Object(IPArcSecurityStrategyVO.class));
	}

	public void batchCommit(List insertBeans, List updateBeans, List delBeans) throws ServiceException {
		if (null != insertBeans) {
			for (Iterator it = insertBeans.iterator(); it.hasNext();) {
				save((IPArcSecurityStrategyVO) it.next());
			}
		}

		if (null != updateBeans) {
			for (Iterator it = updateBeans.iterator(); it.hasNext();) {
				IPArcSecurityStrategyVO ssVo = (IPArcSecurityStrategyVO) it.next();
				if (ssVo.getStrategyky() == null) {
					save(ssVo);
				} else {
					update(ssVo);
				}
			}
		}

		if (null != delBeans) {
			for (Iterator it = delBeans.iterator(); it.hasNext();) {
				IPArcSecurityStrategyVO ssVo = (IPArcSecurityStrategyVO) it.next();
				if (ssVo.getStrategyky() != null) {
					delete(ssVo);
				}
			}
		}
		// 重新加载
		init();
	}

	private void delete(IPArcSecurityStrategyVO ssVo) throws ServiceException {
		delete_Hibernate_Object(ssVo);
		strategyMap.remove(ssVo.getStrategyName());

		SessionUserHolder user = (SessionUserHolder) getBean("sessionUserHolder");
		logDataService.saveLog(IPAuditLogVO.BIZ_TYPE_SYS_MAINTAIN, IPAuditLogVO.OP_CODE_DELETE, user.getStaffId(), user
				.getLoginIp(), PropertyUtil.getPropertyByKey(AppConstants.MSG_INFO_APP_2003) + IPAuditLogVO.SEPARATE
				+ ssVo.getStrategyky() + IPAuditLogVO.SEPARATE + ssVo.getStrategyDesc());
	}

	private void update(IPArcSecurityStrategyVO ssVo) throws ServiceException {
		ssVo.setDelFlag(IPArcSecurityStrategyVO.DEL_FLAG_NORMAL);
		update_Hibernate_Object(ssVo);
		strategyMap.put(ssVo.getStrategyName(), ssVo);
		SessionUserHolder user = (SessionUserHolder) getBean("sessionUserHolder");
		logDataService.saveLog(IPAuditLogVO.BIZ_TYPE_SYS_MAINTAIN, IPAuditLogVO.OP_CODE_UPDATE, user.getStaffId(), user
				.getLoginIp(), PropertyUtil.getPropertyByKey(AppConstants.MSG_INFO_APP_2003) + IPAuditLogVO.SEPARATE + ssVo.getStrategyky()
				+ IPAuditLogVO.SEPARATE + ssVo.getStrategyDesc());
	}

	private void save(IPArcSecurityStrategyVO ssVo) throws ServiceException {
		IPKGenerator keyGen = (IPKGenerator) getBean(IPKGenerator.BEAN_ID);
		String id = keyGen.getUUIDKey(ssVo);
		ssVo.setStrategyky(id);
		ssVo.setDelFlag(IPArcSecurityStrategyVO.DEL_FLAG_NORMAL);
		save_Hibernate_Object(ssVo);
		strategyMap.put(ssVo.getStrategyName(), ssVo);

		SessionUserHolder user = (SessionUserHolder) getBean("sessionUserHolder");
		logDataService.saveLog(IPAuditLogVO.BIZ_TYPE_SYS_MAINTAIN, IPAuditLogVO.OP_CODE_SAVE, user.getStaffId(), user
				.getLoginIp(), PropertyUtil.getPropertyByKey(AppConstants.MSG_INFO_APP_2003) + IPAuditLogVO.SEPARATE + ssVo.getStrategyky()
				+ IPAuditLogVO.SEPARATE + ssVo.getStrategyDesc());
	}

	public String getStrategyValue(String strategyName) {
		IPArcSecurityStrategyVO ret = (IPArcSecurityStrategyVO) strategyMap.get(strategyName);
		if (ret != null) {
			return ret.getStrategyValue();
		}
		return null;
	}

	public Integer getMaxFailedLoginCount(String id) {
		//if (null != id && id.length() > 0) {
			String rv = getGroupStrategyValue(id, MAX_FAILED_LOGIN_COUNT);
			if (rv != null && "-1".equals(rv.trim())) {
				return new Integer("9999");
			}
			if (rv != null && rv.length() > 0) {
				return new Integer(rv);
			}
		//}

		Object o = strategyMap.get(MAX_FAILED_LOGIN_COUNT);
		if (o != null) {
			return new Integer(((IPArcSecurityStrategyVO) o).getStrategyValue());
		}
		return new Integer(DEFAULT_MAX_FAILED_LOGIN_COUNT);
	}

	public String getAdminRoleCode() {
		Object o = strategyMap.get(ADMIN_ROLECODE);
		if (o != null) {
			return ((IPArcSecurityStrategyVO) o).getStrategyValue();
		}
		return DEFAULT_ADMIN_ROLECODE;
	}

	public String getAdminStaffId() {
		Object o = strategyMap.get(ADMIN_STAFFID);
		if (o != null) {
			return ((IPArcSecurityStrategyVO) o).getStrategyValue();
		}
		return DEFAULT_ADMIN_STAFFID;
	}

	public Integer getPasswordExpireDays(String id) {
		//if (null != id && id.length() > 0) {
			String rv = getGroupStrategyValue(id, PASSWORD_EXPIRE_DAYS);
			if (rv != null && "-1".equals(rv.trim())) {
				return new Integer("9999");
			}
			if (rv != null && rv.length() > 0) {
				return new Integer(rv);
			}
		//}

		Object o = strategyMap.get(PASSWORD_EXPIRE_DAYS);

		if (o != null) {
			return new Integer(((IPArcSecurityStrategyVO) o).getStrategyValue());
		}
		return new Integer(DEFAULT_PASSWORD_EXPIRE_DAYS);
	}

	public String getDefaultPasswd(String id) {
		//if (null != id && id.length() > 0) {
			String rv = getGroupStrategyValue(id, DEFAILT_PASSWORD);
			if (rv != null && rv.length() > 0) {
				return rv;
			}
		//}

		Object o = strategyMap.get(DEFAILT_PASSWORD);

		if (o != null) {
			return ((IPArcSecurityStrategyVO) o).getStrategyValue();
		}
		return DEFAULT_DEFAULT_PASSWORD;
	}

	public static String getDEFAULT_ADMIN_STAFFID() {
		return DEFAULT_ADMIN_STAFFID;
	}

	public static String getPASSWORD_EXPIRE_DAYS() {
		return PASSWORD_EXPIRE_DAYS;
	}

	public Integer getPasswordModifiedTimes(String id) {
		//if (null != id && id.length() > 0) {
			String rv = getGroupStrategyValue(id, PASSWORD_MODIFIED_TIMES);
			if (rv != null && "-1".equals(rv.trim())) {
				return new Integer("-1");
			}
			if (rv != null && rv.length() > 0) {
				return new Integer(rv);
			}
		//}

		Object o = strategyMap.get(PASSWORD_MODIFIED_TIMES);

		if (o != null) {
			return new Integer(((IPArcSecurityStrategyVO) o).getStrategyValue());
		}
		return new Integer(DEFAULT_PASSWORD_MODIFIED_TIMES);
	}

	public List getAllPwdHistory(Map map) throws ServiceException {
		return this.find_iBatis("auth.getPwdHisttoryByStaffid", map);
	}

	public boolean isFirstModifyPwd(String id) {
		//if (null != id && id.length() > 0) {
			String rv = getGroupStrategyValue(id, FIRST_MODIFY_PASSWORD);
			if (rv != null && rv.length() > 0) {
				if ("yes".equals(rv)) {
					return true;
				} else {
					return false;
				}
			}
		//}

		Object o = strategyMap.get(FIRST_MODIFY_PASSWORD);

		if (o != null) {
			String temp = ((IPArcSecurityStrategyVO) o).getStrategyValue();
			if ("yes".equals(temp)) {
				return true;
			}
		}
		return false;
	}

	public Integer getPasswdMinLen(String id) {
		//if (null != id && id.length() > 0) {
			String rv = getGroupStrategyValue(id, PASSWORD_MIN_LENGTH);
			if (rv != null && rv.length() > 0) {
				return new Integer(rv);
			}
		//}

		Object o = strategyMap.get(PASSWORD_MIN_LENGTH);

		if (o != null) {
			return new Integer(((IPArcSecurityStrategyVO) o).getStrategyValue());
		}
		return new Integer(DEFAULT_PASSWORD_MIN_LENGTH);
	}

	public boolean isPasswordNeedZuhe(String id) {
		//if (null != id && id.length() > 0) {
			String rv = getGroupStrategyValue(id, PASSWORD_NEED_ZUHE);
			if (rv != null && rv.length() > 0) {
				if ("yes".equals(rv)) {
					return true;
				} else {
					return false;
				}
			}
		//}

		Object o = strategyMap.get(PASSWORD_NEED_ZUHE);

		if (o != null) {
			String temp = ((IPArcSecurityStrategyVO) o).getStrategyValue();
			if ("yes".equals(temp)) {
				return true;
			}
		}
		return false;
	}

	public String getGroupStrategyValue(String staffId, String strategyName) {
		List l = null;
		
		if(staffId!=null){
			Map m = new HashMap();
			m.put("staffId", staffId);
			m.put("strategyName", strategyName.toUpperCase());
			

			try {
				l = find_iBatis("auth.getSuperGroupStrategyValue", m);// 查询该用户是否属于超级管理员组
			} catch (ServiceException e) {
				logger.warn(e);
			}

			if (l != null && l.size() > 0) {// 只要有一个组为超级系统管理员组,就使用该组的策略
				;
				return (String) l.get(0);
			}
		}

		Map m1 = new HashMap();
		m1.put("strategyName", strategyName.toUpperCase());
		try {
			l = find_iBatis("auth.getDefaultGroupStrategyValue", m1);// 查询默认安全策略组
		} catch (ServiceException e) {
			logger.warn(e);
		}

		if (l != null && l.size() > 0) {
			;
			return (String) l.get(0);
		}

		return "";

	}

	public ILogDataService getLogDataService() {
		return logDataService;
	}

	public void setLogDataService(ILogDataService logDataService) {
		this.logDataService = logDataService;
	}

	/**
	 * 不进行组策略查询
	 */
	public Integer getSysSession() {
		Object o = strategyMap.get(SYSTEM_SESSION);
		if (o != null) {
			String temp = ((IPArcSecurityStrategyVO) o).getStrategyValue();
			if (temp != null && temp.length() > 0) {
				return new Integer(temp);
			}
		}
		return new Integer(DEFAULT_SYSTEM_SESSION);
	}

	public Integer getUserSession(String id) {
		//if (null != id && id.length() > 0) {
			String rv = getGroupStrategyValue(id, USER_SESSION);
			if (rv != null && rv.length() > 0) {
				return new Integer(rv);
			}
		//}
		Object o = strategyMap.get(USER_SESSION);
		if (o != null) {
			return new Integer(((IPArcSecurityStrategyVO) o).getStrategyValue());
		}
		return new Integer(DEFAULT_USER_SESSION);
	}

	public List getAllStrategies(String extFlag) throws ServiceException {
		String sql = "from IPArcSecurityStrategyVO";
		HqlWrapper wrapper = new HqlWrapper();
		wrapper.setCondition("extFlag", HqlWrapper.EQUAL, extFlag);
		String[] propertyNames = StringUtil.listToStrArray(wrapper.getPropertyNames());
		String[] operators = StringUtil.listToStrArray(wrapper.getOperators());
		List valuesList = wrapper.getValues();
		Object[] values = valuesList == null || valuesList.size() == 0 ? null : valuesList.toArray();
		String orderBy = null;
		String groupBy = null;
		String otherCause = null;
		Object[] result = this.find_Hibernate_ComposedHQL(sql, propertyNames, operators, values, 0, 999999, true,
				orderBy, groupBy, otherCause);
		List l = (ArrayList) result[0];
		if (l.size() > 0) {
			return l;
		}
		return null;
	}

	/**
	 * 根据策略名称查找冲突解决方案
	 */
	public String getStrategyMethod(String strategyName) {
		IPArcSecurityStrategyVO ret = (IPArcSecurityStrategyVO) strategyMap.get(strategyName.toLowerCase());
		if (ret != null) {
			return ret.getConflictMethod();
		}
		return null;
	}

	/**
	 * 根据用户编号找到用户对应的安全策略值情况
	 * 
	 * @param staffId
	 *            用户编号
	 * @return
	 * @throws ServiceException
	 */
	public List getSelfStrategies(String staffId) throws ServiceException {
		List list = (findAll_Hibernate_Object(IPArcSecurityStrategyVO.class));

		// 将安全策略值设置为该用户对应的安全策略值
		for (int i = 0; i < list.size(); i++) {
			IPArcSecurityStrategyVO vo = (IPArcSecurityStrategyVO) list.get(i);
			String value = getGroupStrategyValue(staffId, vo.getStrategyName());
			if (value == null || value.equals("")) {
				Object o = strategyMap.get(vo.getStrategyName().toLowerCase());
				if (o != null) {
					value = ((IPArcSecurityStrategyVO) o).getStrategyValue();
				}
			}
			vo.setStrategyValue(value);
		}
		return list;
	}
	
	/**
	 * 根据用户对应组查找密码设置方式策略的值（个性）
	 * @param id  用户      
	 * @param ignoreCase
	 * @return 策略值
	 */
	public String getPwdSetting(String id) {
		String rv = getGroupStrategyValue(id, PWD_SETTING);
		if (rv != null && rv.length() > 0) {
				return rv;
		}
		

		Object o = strategyMap.get(PWD_SETTING);

		if (o != null) {
			return ((IPArcSecurityStrategyVO) o).getStrategyValue();
		}
		return DEFAULT_PWD_SETTING;
	}

	
	/**
	 * 根据用户对应组查找自动解锁用户时间(小时)
	 * @param id
	 * @return
	 */
	public Integer getAutoEnableTime(String id) {
		String rv = getGroupStrategyValue(id, AUTO_ENABLE_TIME);
		if (rv != null && "NA".equals(rv.trim())) {
			return new Integer("99999999");
		}
		if (rv != null && rv.length() > 0) {
			return new Integer(rv);
		}

		Object o = strategyMap.get(AUTO_ENABLE_TIME);

		if (o != null) {
			return new Integer(((IPArcSecurityStrategyVO) o).getStrategyValue());
		}
		return new Integer(DEFAULT_AUTO_ENABLE_TIME);
	}
}
